package com.zsc.edu.gateway.modules.message.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zsc.edu.gateway.framework.mybatisplus.DataPermission;
import com.zsc.edu.gateway.framework.security.UserDetailsImpl;
import com.zsc.edu.gateway.modules.message.dto.UserNoticeDto;
import com.zsc.edu.gateway.modules.message.query.AdminNoticeQuery;
import com.zsc.edu.gateway.modules.message.query.UserNoticeQuery;
import com.zsc.edu.gateway.modules.message.service.UserNoticeService;
import com.zsc.edu.gateway.modules.message.vo.AdminNoticeVo;
import com.zsc.edu.gateway.modules.message.vo.UserNoticeVo;
import com.zsc.edu.gateway.modules.operationLog.entity.OperationLogAnnotation;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 用户消息Controller
 *
 * @author harry_yao
 */
@AllArgsConstructor
@RestController
@RequestMapping("api/rest/notice")
public class UserNoticeController {

    private final UserNoticeService service;

    /**
     * 普通用户查看消息详情
     *
     * @param userDetails 操作用户
     * @param noticeId   消息ID
     * @return 用户消息详情
     */
    @GetMapping("/self/{noticeId}")
    public UserNoticeVo selfDetail(@AuthenticationPrincipal UserDetailsImpl userDetails, @PathVariable("noticeId") Long noticeId) {
        return service.detail(noticeId, userDetails.getId());
    }

    /**
     * 普通用户分页查询消息，不能设置查询参数userId和username
     *
     * @param userDetails 操作用户
     * @param query       查询参数
     * @return 分页数据
     */
    @GetMapping("/self")
    public IPage<UserNoticeVo> selfPage(Page<UserNoticeVo> pageParam, @AuthenticationPrincipal UserDetailsImpl userDetails, UserNoticeQuery query) {
        query.userId = userDetails.id;
        query.name = null;
        return service.page(pageParam, query);
    }

    /**
     * 普通用户统计自己未读消息数量
     *
     * @param userDetails 操作用户
     * @return 数据
     */
    @GetMapping("/countUnread")
    public int countUnread(@AuthenticationPrincipal UserDetailsImpl userDetails) {
        return service.countUnread(userDetails);
    }

    /**
     * 普通用户确认消息已读，如果提交的已读消息ID集合为空，则将所有未读消息设为已读
     *
     * @param userDetails 操作用户
     * @param noticeIds  已读消息ID集合
     * @return 确认已读数量
     */
    @PatchMapping("/read")
    public Boolean acknowledge(@AuthenticationPrincipal UserDetailsImpl userDetails, @RequestBody List<Long> noticeIds) {
        return service.markAsRead(userDetails, noticeIds);
    }

    /**
     * 普通用户确认消息已读，如果提交的已读消息ID集合为空，则将所有未读消息设为已读
     *
     * @param userDetails 操作用户
     * @return 确认已读数量
     */
    @PatchMapping("/readAll")
    public Boolean readAll(@AuthenticationPrincipal UserDetailsImpl userDetails) {
        return service.markAllAsRead(userDetails);
    }

    /**
     * 管理查询消息详情
     *
     * @param noticeId 消息ID
     * @return 用户消息详情
     */
    @GetMapping("/{userId}/{noticeId}")
    @PreAuthorize("hasAuthority('message:notice:query')")
    public UserNoticeVo detail(@PathVariable("userId") Long userId, @PathVariable("noticeId") Long noticeId) {
        return service.detail(noticeId, userId);
    }

    /**
     * 管理员分页查询消息
     *
     * @param query 查询参数
     * @return 分页数据
     */
    @DataPermission(tableAlias = "su")
    @GetMapping
    @PreAuthorize("hasAuthority('message:notice:query')")
    public IPage<AdminNoticeVo> page(Page<AdminNoticeVo> page, AdminNoticeQuery query) {
        return service.getAdminNoticePage(page, query);
    }

    /**
     * 管理员手动创建消息
     *
     * @param dto 表单数据
     * @return 消息列表
     */
    @PostMapping
    @PreAuthorize("hasAuthority('message:notice:create')")
    @OperationLogAnnotation(content = "'消息'", operationType = "新建")
    public Boolean create(@RequestBody UserNoticeDto dto) {
        return service.createByAdmin(dto);
    }
}
